package com.example.mobilesafe.activity;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.animation.AlphaAnimation;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.example.mobilesafe.R;
import com.example.mobilesafe.constant.ConstantValue;
import com.example.mobilesafe.utils.SharedPreferencesUtil;
import com.example.mobilesafe.utils.StreamUtil;
import com.example.mobilesafe.utils.ToastUtil;
import com.lidroid.xutils.HttpUtils;
import com.lidroid.xutils.exception.HttpException;
import com.lidroid.xutils.http.ResponseInfo;
import com.lidroid.xutils.http.callback.RequestCallBack;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

public class SplashActivity extends AppCompatActivity {

    /**
     * 文本控件
     */
    private TextView tv_version_name;

    /**
     * 根布局
     */
    private RelativeLayout rl_root;

    /**
     * 本地版本号
     */
    private int mLocalVersionCode;

    /**
     * 更新时描述信息
     */
    private String mVersionDes;

    /**
     * 更新时的URL
     */
    private String mDownloadUrl;

    private static final String tag = "SplashActivity";

    /**
     * Handler对象
     */
    private Handler mHandler = new Handler(){
        @Override
        public void handleMessage(@NonNull Message msg) {
            switch (msg.what){
                case UPDATE_VERSION:
                    // 1.弹出对话框，提示用户更新
                    showUpdateDialog();
                    break;
                case ENTER_HOME:
                    // 2.直接进入应用程序主界面
                    enterHome();
                    break;
                case URL_ERROR:
                    // 3.弹出URL错误
                    ToastUtil.show(SplashActivity.this,"url异常");
                    enterHome();
                    break;
                case IO_ERROR:
                    // 4.弹出IO错误
                    ToastUtil.show(SplashActivity.this,"IO异常");
                    enterHome();
                    break;
                case JSON_ERROR:
                    // 5.弹出JSON错误
                    ToastUtil.show(SplashActivity.this,"json异常");
                    enterHome();
                    break;
                default:break;
            }
        }
    };

    /**
     * 更新新版本的状态码
     */
    private static final int UPDATE_VERSION = 100;

    /**
     * 进入应用程序主界面的状态码
     */
    private static final int ENTER_HOME = 101;

    /**
     * URL地址出错的状态码
     */
    private static final int URL_ERROR = 102;

    /**
     * IO操作出错的状态码
     */
    private static final int IO_ERROR = 103;

    /**
     * JSON解析出错的状态码
     */
    private static final int JSON_ERROR = 104;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_splash);

        // 初始化UI
        initUI();

        // 初始化数据
        initData();

        // 初始化动画
        initAnimation();

        // 初始化数据库
        initDB();

        // 生成快捷方式
        if (!SharedPreferencesUtil.getBoolean(this,ConstantValue.HAS_SHORTCUT,false)){
            initShortCut();
        }
    }

    /**
     * 1.初始化UI
     */
    private void initUI() {
        tv_version_name = findViewById(R.id.tv_version_name);
        rl_root = findViewById(R.id.rl_root);
    }

    /**
     * 2.初始化数据
     */
    private void initData() {
        // 1.获取应用版本名称
        String versionName = getVersionName();
        // 2.将应用版本名称设置到文本控件中
        tv_version_name.setText("版本名称：" + versionName);
        // 3.获取本地（客户端）版本号
        mLocalVersionCode = getVersionCode();
        // 4.获取服务端版本号（客户端发请求，服务端给响应(Json、Xml)）
        /*
        Json中内容应该包括：
            1.更新版本的名称 versionName
            2.新版本的描述信息 versionDes
            3.服务器的版本号 versionCode
            4.新版本apk下载地址 downloadUrl
         */
        if (SharedPreferencesUtil.getBoolean(this, ConstantValue.OPEN_UPDATE,false)){
            checkVersion();
        }
        else {
                // 这里不调用enterHome()，是因为直接调用会很快进入主界面（HomeActivity)，跳过闪屏页面（SplashActivity）
                // 也不选择Thread.sleep(4000)后再enterHome()，是因为在主线程阻塞4秒风险太大，若到达7秒则会ANR
                // 所以选择发送消息的形式来实现在没有选择“自动更新”的情况下直接进入主界面，即时发送消息后，延时4秒钟，否则会太快进入主界面
            mHandler.sendEmptyMessageDelayed(ENTER_HOME,4000);
        }
    }

    /**
     * 3.获取版本应用名称（在清单文件中）
     * @return 版本名称
     */
    private String getVersionName() {
        // 1.获取包管理对象packageManager 
        PackageManager pm = getPackageManager();
        // 2.从包管理对象中，获取指定包名的基本信息（版本名称，版本号）,第二个参数传0代表获取基本信息
        try {
            PackageInfo packageInfo = pm.getPackageInfo(getPackageName(), 0);
            // 3.获取并返回版本名称
            return packageInfo.versionName;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        // 4.抛出异常
        return null;
    }

    /**
     * 4.获取版本号（在清单文件中）
     * @return 版本号
     */
    private int getVersionCode() {
        // 1.获取包管理对象packageManager
        PackageManager pm = getPackageManager();
        // 2.从包管理对象中，获取指定包名的基本信息（版本名称，版本号）,第二个参数传0代表获取基本信息
        try {
            PackageInfo packageInfo = pm.getPackageInfo(getPackageName(), 0);
            // 3.获取并返回版本编号
            return packageInfo.versionCode;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return 0;
    }

    /**
     * 5.获取服务端版本号
     */
    private void checkVersion() {
        // 发送请求，获取数据，参数则为请求json的链接地址
        new Thread(){
            @Override
            public void run() {
                // 0.获取message对象
                Message msg = Message.obtain();
                long startTime = System.currentTimeMillis();// 获取时间戳
                try {
                    // 1.封装url地址
                    URL url = new URL("http://10.0.2.2:8080/update74.json");
                    // 2.开启一个链接
                    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                    // 3.设置常见请求参数（请求头）
                    connection.setConnectTimeout(2000); // 请求超时
                    connection.setReadTimeout(2000); // 读取超时
                    //connection.setRequestMethod("GET"); // 请求方式，默认是get请求方式
                    // 4.获取相应码,200为请求成功
                    if (connection.getResponseCode() == 200){
                        // 5.以流的形式将数据获取下来
                        InputStream is = connection.getInputStream();
                        // 6.将流转换成字符串（工具封装类）
                        String json = StreamUtil.streamToString(is);
                        // 7.json解析
                        JSONObject jsonObject = new JSONObject(json);
                        String versionName = jsonObject.getString("versionName");
                        mVersionDes = jsonObject.getString("versionDes");
                        String versionCode = jsonObject.getString("versionCode");
                        mDownloadUrl = jsonObject.getString("downloadUrl");
                        // 8.比对版本号（服务器版本号 > 本地版本号，提示用户更新）
                        if (Integer.parseInt(versionCode) > mLocalVersionCode){
                            // 9.提示用户更新，弹出对话框（UI），需要使用到消息机制
                            msg.what = UPDATE_VERSION;
                        }else {
                            // 10.不需要更新，直接进入应用程序主界面
                            msg.what = ENTER_HOME;
                        }
                    }
                }catch (MalformedURLException e) {
                    e.printStackTrace();
                    msg.what = URL_ERROR;
                }catch (IOException e) {
                    e.printStackTrace();
                    msg.what = IO_ERROR;
                }
                catch (JSONException e) {
                    e.printStackTrace();
                    msg.what = JSON_ERROR;
                }finally {
                    // 11.指定睡眠时间，请求网络的时长超过4秒则不做处理，若小于4秒，则强制让其睡眠满4秒
                    long endTime = System.currentTimeMillis();
                    if (endTime - startTime < 4000){
                        try {
                            Thread.sleep(4000 - (endTime - startTime));
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                    // 12.发送消息
                    mHandler.sendMessage(msg);
                }
            }
        }.start();
    }

    /**
     * 6.进入应用程序的主界面
     */
    private void enterHome() {
        Intent intent = new Intent(this, HomeActivity.class);
        startActivity(intent);
        finish(); // 开启新界面后，将导航界面销毁掉
    }

    /**
     * 7.弹出更新对话框
     */
    private void showUpdateDialog() {
        final AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setIcon(R.drawable.ic_launcher); // 设置左上角图标
        builder.setTitle("版本更新"); // 设置标题
        builder.setMessage(mVersionDes); // 设置描述内容
        builder.setPositiveButton("立即更新", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                // 下载apk，需要apk的链接地址，即downloadUrl
                downloadApk();
            }
        });// 积极按钮，“是”
        builder.setNegativeButton("稍后再说", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                // 取消对话框，进入主界面
                enterHome();
            }
        });// 消极按钮，“否”
        builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
            @Override
            public void onCancel(DialogInterface dialog) {
                // 按下回退后，进入主界面，然后隐藏对话框
                enterHome();
                dialog.dismiss();
            }
        });// 回退按钮
        builder.show();
    }

    /**
     * 8.APK下载
     */
    private void downloadApk() {
        // 需要apk下载链接地址，放置apk的所在路径
        // 1.判断sd卡是否可用，是否挂载
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
            // 2.获取sd卡路径
            // String path = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "app-release.apk";
            String path = (SplashActivity.this).getExternalFilesDir(null) + File.separator + "app-release.apk";
            Log.i(tag,"路径为：" + path);
            // 3.发送请求，获取Apk，并且放置到指定路径(下载地址，下载应用的放置位置，回调方法)
            HttpUtils httpUtils = new HttpUtils();
            httpUtils.download(mDownloadUrl, path, new RequestCallBack<File>() {
                @Override
                public void onSuccess(ResponseInfo<File> responseInfo) {
                    // 下载成功（下载过后的放置在sd卡中apk）
                    Log.i(tag,"下载成功！");
                    File file = responseInfo.result;
                    installApk(file);
                }

                @Override
                public void onFailure(HttpException e, String s) {
                    // 下载失败
                    Log.i(tag,"下载失败！");
                    e.printStackTrace();
                }

                @Override
                public void onStart() {
                    // 刚刚开始下载
                    Log.i(tag,"刚刚开始下载！");
                    super.onStart();
                }

                @Override
                public void onLoading(long total, long current, boolean isUploading) {
                    // 下载过程（下载文件大小，当前的下载位置，是否正在下载）
                    Log.i(tag,"下载中......文件大小为" + total + "当前的下载位置为" + current);
                    super.onLoading(total, current, isUploading);
                }
            });
        }
    }

    /**
     * 9.APK安装
     * @param file 安装文件
     */
    private void installApk(File file) {
        // 系统应用界面，源码，安装apk入口
        Intent intent = new Intent("android.intent.action.VIEW");
        intent.addCategory("android.intent.category.DEFAULT");
        // 文件作为数据源
        // intent.setData(Uri.fromFile(file));
        // 设置安装的类型
        // intent.setType("application/vnd.android.package-archive");
        intent.setDataAndType(Uri.fromFile(file),"application/vnd.android.package-archive");
        startActivityForResult(intent,0);
    }

    /**
     * 10.开启一个Activity后，返回结果
     * @param requestCode
     * @param resultCode
     * @param data
     */
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        enterHome();
        super.onActivityResult(requestCode, resultCode, data);
    }

    /**
     * 11.初始化动画
     */
    private void initAnimation() {
        AlphaAnimation alphaAnimation = new AlphaAnimation(0,1);
        alphaAnimation.setDuration(3000);
        rl_root.startAnimation(alphaAnimation);
    }

    /**
     * 12.初始化数据库
     */
    private void initDB(){
        // 归属地数据拷贝过程
        initAddressDB("address.db");
        // 常用号码数据库的拷贝过程
        initAddressDB("commonnum.db");
        // 病毒数据库的拷贝过程
        initAddressDB("antivirus.db");
    }

    /**
     * 13.初始化归属地数据库
     * @param dbName 数据库名称
     */
    private void initAddressDB(String dbName) {
        // 1.在files文件夹下创建同名数据库
        File filesDir = getFilesDir();
        File file = new File(filesDir, dbName);
        if (file.exists()){
            return;
        }
        InputStream stream = null;
        FileOutputStream fileOutputStream = null;
        // 2.读取第三方资产目录下的文件
        try {
            stream = getAssets().open(dbName);
            // 3.将读取的内容写入到指定文件夹的文件中
            fileOutputStream = new FileOutputStream(file);
            // 4.每次的读取内容大小
            byte[] bytes = new byte[1024];
            int temp = -1;
            while ( (temp = stream.read(bytes)) != -1){
                fileOutputStream.write(bytes,0,temp);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (stream != null && fileOutputStream != null){
                try {
                    stream.close();
                    fileOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 14.生成快捷方式
     */
    private void initShortCut() {
        // 1.给intent维护图标，名称
        Intent intent = new Intent("com.android.launcher.action.INSTALL_SHORTCUT");
        intent.putExtra(Intent.EXTRA_SHORTCUT_ICON, BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher));
        intent.putExtra(Intent.EXTRA_SHORTCUT_NAME,"手机卫士");
        // 2.点击快捷方式后跳转到的Activity，维护开启的意图对象
        Intent shortCutIntent = new Intent("android.intent.action.HOME");
        shortCutIntent.addCategory("android.intent.category.DEFAULT");
        intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT,shortCutIntent);
        // 3.发送广播
        sendBroadcast(intent);
        // 4.告知Sp已经生成了快捷方式
        SharedPreferencesUtil.putBoolean(this,ConstantValue.HAS_SHORTCUT,true);
    }
}